package com.tbit.main.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.tbit.common.constant.PerformanceTypeConstant;
import com.tbit.common.entity.view.PageResult;
import com.tbit.main.constant.AccountConfigExtConstant;
import com.tbit.main.constant.MachineAbnormalConstant;
import com.tbit.main.constant.enums.PerformanceBizType;
import com.tbit.main.constant.enums.PerformanceRuleType;
import com.tbit.main.dao.core.AccountUserDao;
import com.tbit.main.dao.core.TagDao;
import com.tbit.main.dao.log.DispatchLogDao;
import com.tbit.main.dao.log.DispatchPerformanceDao;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.pojo.maintain_performance.Range;
import com.tbit.main.pojo.maintain_performance.config.DispatchPerformanceConfig;
import com.tbit.main.pojo.maintain_performance.constant.RuleTypeConstant;
import com.tbit.main.pojo.maintain_performance.group.IntervalAndValidityBasedGroup;
import com.tbit.main.pojo.maintain_performance.rule.*;
import com.tbit.main.pojo.maintain_performance.stat.*;
import com.tbit.main.service.AccountConfigExtService;
import com.tbit.main.service.MachineAbnormalService;
import com.tbit.main.service.RedisService;
import com.tbit.main.service.TagService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author <a href="mailto:zheng.zebiao@tbit.com.cn">zb</a>
 * @since 2025/3/4
 */
@Slf4j
@Service
@AllArgsConstructor
public class DispatchPerformanceService extends ServiceImpl<DispatchPerformanceDao, DispatchPerformance> {
    final AccountUserDao accountUserDao;
    final AccountConfigExtService configExtService;
    final PerformanceRuleGroupService ruleGroupService;
    final RedisService redisService;
    final TagDao tagDao;
    final DispatchLogDao dispatchLogDao;
    final MachineAbnormalService abnormalService;
    final DispatchPerformanceLogService performanceLogService;
    final TagService tagService;

    /**
     * 查询总览数据
     */
    public List<PerformanceOverviewResp> queryOverviewPage(PerformanceOverviewReq req,AccountUser loginAccountUser) {
        //getBaseMapper().queryOverviewPage(req);
        List<PerformanceOverviewResp> list = this.getPerformanceList(req,loginAccountUser);

        if (CollUtil.isNotEmpty(list)) {
            String accountUserIds = list.stream()
                    .map(PerformanceOverviewResp::getAccountUserId)
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
            Map<Integer, AccountUser> accountUserMap = Optional.ofNullable(accountUserDao.getByIds(accountUserIds))
                    .map(x -> x.stream()
                            .collect(Collectors.toMap(AccountUser::getAccountUserId, Function.identity()))
                    )
                    .orElse(Collections.emptyMap());

            for (PerformanceOverviewResp detail : list) {
                // 补充运维人员信息
                AccountUser accountUser = accountUserMap.get(detail.getAccountUserId());
                if (accountUser != null) {
                    detail.setAccountUserName(accountUser.getName());
                    detail.setAccountUserPhone(accountUser.getPhone());
                    detail.setDelFlag(accountUser.getDelFlag());
                }
            }
        }
        return list;
    }

    /**
     * 查询绩效统计
     *
     * @param req
     * @return
     */
    public PerformanceCountResp queryPerformanceCount(PerformanceCountReq req) {
        return getBaseMapper().queryPerformanceCount(req);
    }

    /**
     * 查询详情数据
     */
    public PageResult<DispatchPerformanceDetail> queryDetailPage(PerformanceDetailReq req) {
        try (Page<DispatchPerformanceDetail> page = PageHelper.startPage(req.getPageNo(), req.getPageSize())) {
            getBaseMapper().queryDetailPage(req);

            if (CollUtil.isNotEmpty(page)) {
                String accountUserIds = page.getResult().stream()
                        .map(DispatchPerformanceDetail::getAccountUserId)
                        .map(String::valueOf)
                        .collect(Collectors.joining(","));
                Map<Integer, AccountUser> accountUserMap = Optional.ofNullable(accountUserDao.getByIds(accountUserIds))
                        .map(x -> x.stream()
                                .collect(Collectors.toMap(AccountUser::getAccountUserId, Function.identity()))
                        )
                        .orElse(Collections.emptyMap());

                for (DispatchPerformanceDetail detail : page) {
                    // 补充运维人员信息
                    AccountUser accountUser = accountUserMap.get(detail.getAccountUserId());
                    if (accountUser != null) {
                        detail.setAccountUserName(accountUser.getName());
                        detail.setAccountUserPhone(accountUser.getPhone());
                    }
                }
            }
            return PageResult.convertPage(page.toPageInfo());
        }
    }

    public static final String DISPATCH_CURR_TAG_KEY = "maintainPerformance:dispatch:tag:";

    public void cacheTags(Integer machineId, List<TagBaseInfo> tags) {
        tagService.cacheTags(machineId, tags);
    }

    public List<TagBaseInfo> getTags(Integer machineId) {
        return tagService.getTags(machineId);
    }

    public static final String ABNORMAL_KEY = "maintainPerformance:dispatch:abnormal:";

    /**
     * 缓存车辆异常，供后续调度绩效使用
     *
     * @param machineId 车辆id
     */
    public void cacheAbnormal(Integer machineId) {
        List<MachineAbnormal> abnormal = abnormalService.getByMachineId(machineId);
        if (CollUtil.isEmpty(abnormal)) {
            return;
        }
        String abnormalTypes = abnormal.stream()
                .map(MachineAbnormal::getAbnormalType)
                .map(String::valueOf)
                .collect(Collectors.joining(","));
        redisService.add(ABNORMAL_KEY + machineId, abnormalTypes, 3, TimeUnit.DAYS);
    }

    /**
     * 获取缓存车辆异常，供后续调度绩效使用
     *
     * @param machineId 车辆id
     * @return 异常类型列表
     */
    public List<Integer> getAbnormalCache(Integer machineId) {
        String value = redisService.get(ABNORMAL_KEY + machineId);
        if (value != null) {
            return Arrays.stream(value.split(","))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    /**
     * 计算并插入绩效
     *
     * @param dl 调度记录
     */
    public void calculateAndInsertPerformance(DispatchLog dl) {
        try {
            if (!Objects.equals(dl.getIsValid(), 1)) {
                return;
            }

            // 检查开关
            AccountConfigExt performanceSwitch = configExtService.getParamKey(dl.getAccountId(), AccountConfigExtConstant.DISPATCH_PERFORMANCE);
            if (performanceSwitch == null || Objects.equals(performanceSwitch.getParamValue(), "0")) {
                return;
            }
            // 获取绩效记录
            DispatchPerformance dp = getOne(Wrappers.<DispatchPerformance>query()
                    .eq(DispatchPerformance.Fields.dispatchLogId, dl.getDispatchLogId())
            );
            if (dp != null) {
                log.info("[调度绩效] 已有记录, 不再计算, 调度记录id: {},调度记录id: {}", dl.getDispatchLogId(), dp.getPerformanceId());
                return;
            }
            // 生成新绩效记录
            log.info("[调度绩效] 生成新绩效记录, 调度记录id: {}", dl.getDispatchLogId());
            dp = new DispatchPerformance();
            dp.setDispatchLogId(dl.getDispatchLogId());
            dp.setAccountId(dl.getAccountId());
            Date dispatchTime = DateUtil.parse(dl.getDispatchTime());
            dp.setOrderCountAfter24Hour(0);
            List<TagBaseInfo> tags = getTags(dl.getMachineId());
            if (!tags.isEmpty()) {
                dp.setBeforeTag(tags.stream()
                        .map(TagBaseInfo::getName)
                        .collect(Collectors.joining(",")));
            }
            // 挪车前状态
            List<Integer> abnormalCache = getAbnormalCache(dl.getMachineId());
            if (!abnormalCache.isEmpty()) {
                StringBuilder abnormalTypes = new StringBuilder();
                for (Integer abnormalType : abnormalCache) {
                    abnormalTypes.append(MachineAbnormalConstant.parse(abnormalType))
                            .append(",");
                }
                dp.setBeforeStatus(abnormalTypes.substring(0, abnormalTypes.length() - 1));
            }
            // 调度时段
            int hour = DateUtil.hour(dispatchTime, true);
            if (hour >= 0 && hour < 6) {
                dp.setDispatchInterval(1);
            } else if (hour >= 6 && hour < 12) {
                dp.setDispatchInterval(2);
            } else if (hour >= 12 && hour < 18) {
                dp.setDispatchInterval(3);
            } else if (hour >= 18 && hour < 24) {
                dp.setDispatchInterval(4);
            }

            // 计算绩效
            List<DispatchPerformanceLog> performanceLogs = new ArrayList<>();
            calculatePerformance(dl, dp, performanceLogs);

            // 绩效记录入库
            save(dp);
            // 保存绩效日志
            if (!performanceLogs.isEmpty()) {
                // 填充绩效记录id
                DispatchPerformance finalDp = dp;
                performanceLogs.forEach(performanceLog -> performanceLog.setPerformanceId(finalDp.getPerformanceId()));
                performanceLogService.insertBatch(performanceLogs);
            }
        } catch (Exception e) {
            log.error("[调度绩效] 计算绩效时发生错误, 调度记录id: {}", dl.getDispatchLogId(), e);
        }
    }

    /**
     * 根据车辆id更新7天内最近一次调度绩效
     *
     * @param machineId 车辆id
     * @param orderNO   订单编号
     */
    public void updatePerformanceByNewOrder(Integer machineId, String orderNO) {
        DispatchLog dl = dispatchLogDao.selectLast7DayFirstValidByMachineId(machineId);
        if (dl == null) {
            return;
        }

        // 检查开关
        AccountConfigExt performanceSwitch = configExtService.getParamKey(dl.getAccountId(), AccountConfigExtConstant.DISPATCH_PERFORMANCE);
        if (performanceSwitch == null || Objects.equals(performanceSwitch.getParamValue(), "0")) {
            return;
        }

        try {
            // 获取绩效记录
            DispatchPerformance dp = getOne(Wrappers.<DispatchPerformance>query()
                    .eq(DispatchPerformance.Fields.dispatchLogId, dl.getDispatchLogId())
            );
            if (dp == null || Objects.equals(dp.getPerformanceType(), PerformanceTypeConstant.MANUAL)) {
                log.info("[调度绩效] 调度记录id: {}, 绩效不存在或者是手动绩效,不处理。", dl.getDispatchLogId());
                return;
            }

            // 获取配置
            DispatchPerformanceConfig config = ruleGroupService.selectBizPerformanceConfig(dl.getAccountId(), DispatchPerformanceConfig::fromRaw, PerformanceBizType.DISPATCH);
            if ((config.getIntervalAndValidityBased() == null || !config.getIntervalAndValidityBased().getEnabled())) {
                return;
            }

            LocalDateTime dispatchTime = DateUtil.parseLocalDateTime(dl.getDispatchTime());
            LocalDateTime orderTime = LocalDateTime.now();
            LocalTime dispatchLocalTime = dispatchTime.toLocalTime();
            LocalTime orderLocalTime = orderTime.toLocalTime();

            BigDecimal performance = dp.getPerformance();
            StringBuilder detail = new StringBuilder(dp.getPerformanceDetail());

            // 调度时间是否在时段、时效规则区间内
            IntervalAndValidityBasedGroup intervalAndValidityBasedGroup = config.getIntervalAndValidityBased();
            // 判断是否超过最大订单数限制 是否开启该规则
            if (intervalAndValidityBasedGroup != null
                    && intervalAndValidityBasedGroup.getEnabled()
                    && (intervalAndValidityBasedGroup.getMaxOrderCount() > dp.getOrderCountAfter24Hour())) {
                List<DispatchPerformanceLog> performanceLogs = new ArrayList<>(1);
                List<IntervalAndValidityBasedRule> rules = intervalAndValidityBasedGroup.getRules();
                for (IntervalAndValidityBasedRule rule : rules) {
                    Range<String> completedDuration = rule.getCompletedDuration();
                    // completedDuration 转换为LocalTime去比较
                    LocalTime start = LocalTime.parse(completedDuration.getStart2Calc());
                    LocalTime end = LocalTime.parse(completedDuration.getEnd2Calc());
                    Range completedRange = new Range<LocalTime>();
                    completedRange.setStart(start);
                    completedRange.setEnd(end);
                    if (completedRange.match(dispatchLocalTime)) {
                        // 调度时间在此时间内
                        String ruleType = rule.getRuleType();
                        switch (ruleType) {
                            case RuleTypeConstant.INTERVAL_BASED_RULE:// 基于时间间隔的规则
                                IntervalAndValidityBasedSubRule subRule = rule.calculatePerformance(dispatchTime, orderTime);
                                if (subRule != null) {
                                    log.info("[调度绩效] 更新调度记录id: {}, 适用订单时段绩效, 时段: {}, 订单号: {}", dp.getDispatchLogId(), subRule.getOrderIntervalOrHour(), orderNO);
                                    performance = performance.add(subRule.getPerformance());
                                    detail.append("产生订单时段绩效: ")
                                            .append(NumberUtil.toStr(subRule.getPerformance()))
                                            .append("(")
                                            .append(subRule.getOrderIntervalOrHour())
                                            .append(");");
                                    DispatchPerformanceLog performanceLog = new DispatchPerformanceLog();
                                    BeanUtil.copyProperties(dp, performanceLog, "performance", "performanceDetail", "remark");
                                    performanceLog.setPerformance(subRule.getPerformance());
                                    performanceLog.setPerformanceDetail("产生订单时段绩效: " + NumberUtil.toStr(subRule.getPerformance()) + "(" + subRule.getOrderIntervalOrHour() + ");");
                                    performanceLog.setRuleType(PerformanceRuleType.INTERVAL.getValue());
                                    performanceLog.setFirstOrderDuration((int) Duration.between(dispatchTime, orderTime).toMinutes());
                                    performanceLog.setOrderCountAfter24Hour(dp.getOrderCountAfter24Hour() + 1);
                                    performanceLog.setRemark("MAIN-INTERVAL_BASED_RULE-产生订单时段");
                                    performanceLogs.add(performanceLog);
                                }
                                break;
                            case RuleTypeConstant.VALIDITY_BASED_RULE: //基于时效的规则
                                long hours = Duration.between(dispatchTime, orderTime).toHours();
                                IntervalAndValidityBasedSubRule subValidityBasedRule = rule.calculatePerformance((int) hours);
                                if (subValidityBasedRule != null) {
                                    log.info("[调度绩效] 更新调度记录id: {}, 适用订单时效绩效, 时效: {}h, 订单号: {}", dp.getDispatchLogId(), subValidityBasedRule.getOrderIntervalOrHour(), orderNO);
                                    performance = performance.add(subValidityBasedRule.getPerformance());
                                    detail.append("产生订单时效绩效: ")
                                            .append(NumberUtil.toStr(subValidityBasedRule.getPerformance()))
                                            .append("(")
                                            .append(subValidityBasedRule.getOrderIntervalOrHour())
                                            .append("小时);");
                                    DispatchPerformanceLog performanceLog = new DispatchPerformanceLog();
                                    BeanUtil.copyProperties(dp, performanceLog, "performance", "performanceDetail", "remark");
                                    performanceLog.setPerformance(subValidityBasedRule.getPerformance());
                                    performanceLog.setPerformanceDetail("产生订单时效绩效: " + NumberUtil.toStr(subValidityBasedRule.getPerformance()) + "(" + subValidityBasedRule.getOrderIntervalOrHour() + "小时);");
                                    performanceLog.setRuleType(PerformanceRuleType.VALIDITY.getValue());
                                    performanceLog.setFirstOrderDuration((int) Duration.between(dispatchTime, orderTime).toMinutes());
                                    performanceLog.setOrderCountAfter24Hour(dp.getOrderCountAfter24Hour() + 1);
                                    performanceLog.setRemark("MAIN-INTERVAL_AND_VALIDITY-产生订单时效");
                                    performanceLogs.add(performanceLog);
                                }
                                break;
                            default:
                                break;
                        }
                    }

                }
                // 保存绩效日志
                if (!performanceLogs.isEmpty()) {
                    performanceLogService.insertBatch(performanceLogs);
                }
            }

            // 更新订单数等信息
            if (dp.getFirstOrderDuration() == null) {
                dp.setFirstOrderDuration((int) Duration.between(dispatchTime, orderTime).toMinutes());
            }
            dp.setOrderCountAfter24Hour(dp.getOrderCountAfter24Hour() + 1);

            // 更新记录
            dp.setPerformance(performance);
            dp.setPerformanceDetail(detail.toString());
            updateById(dp);

        } catch (Exception e) {
            log.error("[调度绩效] 更新绩效时发生错误, 调度记录id: {}", dl.getDispatchLogId(), e);
        }
    }

    /**
     * 计算调度绩效
     */
    private void calculatePerformance(DispatchLog dl, DispatchPerformance dp, List<DispatchPerformanceLog> performanceLogs) {
        DispatchPerformanceConfig config = ruleGroupService.selectBizPerformanceConfig(dl.getAccountId(), DispatchPerformanceConfig::fromRaw, PerformanceBizType.DISPATCH);

        BigDecimal performance = BigDecimal.ZERO;
        StringBuilder detail = new StringBuilder();

        // 基础绩效
        if (config.getBasic() != null && config.getBasic().getEnabled()) {
            log.info("[调度绩效] 调度记录id: {}, 适用基础绩效", dp.getDispatchLogId());
            BigDecimal validPerf = config.getBasic().getValidPerformance();
            performance = performance.add(validPerf);
            detail.append("基础绩效: ")
                    .append(NumberUtil.toStr(validPerf))
                    .append(";");
            DispatchPerformanceLog performanceLog = new DispatchPerformanceLog();
            BeanUtil.copyProperties(dp, performanceLog, "performance", "performanceDetail", "remark");
            performanceLog.setPerformance(validPerf);
            performanceLog.setPerformanceDetail("基础绩效: " + NumberUtil.toStr(validPerf) + ";");
            performanceLog.setRuleType(PerformanceRuleType.BASIC.getValue());
            performanceLog.setRemark("MAIN-BASIC-基础绩效");
            performanceLogs.add(performanceLog);
        }

        // 闲置时长
        if (config.getUnusedTimeBased() != null && config.getUnusedTimeBased().getEnabled()) {
            for (UnusedTimeBasedRule subRule : config.getUnusedTimeBased().getSubRules()) {
                if (subRule.getUnusedTime().match(dl.getIdleTime())) {
                    log.info("[调度绩效] 调度记录id: {}, 适用闲置时长绩效, 闲置时长: {}h", dp.getDispatchLogId(), subRule.getUnusedTime());
                    performance = performance.add(subRule.getPerformance());
                    detail.append("闲置时长绩效: ")
                            .append(NumberUtil.toStr(subRule.getPerformance()))
                            .append("(")
                            .append(subRule.getUnusedTime())
                            .append("小时);");
                    DispatchPerformanceLog performanceLog = new DispatchPerformanceLog();
                    BeanUtil.copyProperties(dp, performanceLog, "performance", "performanceDetail", "remark");
                    performanceLog.setPerformance(subRule.getPerformance());
                    performanceLog.setPerformanceDetail("闲置时长绩效: " + NumberUtil.toStr(subRule.getPerformance()) + "(" + subRule.getUnusedTime() + "小时);");
                    performanceLog.setRuleType(PerformanceRuleType.UNUSED_TIME.getValue());
                    performanceLog.setRemark("MAIN-UNUSED_TIME-闲置时长");
                    performanceLogs.add(performanceLog);
                    break;
                }
            }
        }

        // 调度距离
        if (config.getDistanceBased() != null && config.getDistanceBased().getEnabled()) {
            for (MoveDistanceRule subRule : config.getDistanceBased().getSubRules()) {
                if (subRule.getDistanceMeter().match(dl.getDistance())) {
                    log.info("[调度绩效] 调度记录id: {}, 适用调度距离绩效, 调度距离: {}m", dp.getDispatchLogId(), subRule.getDistanceMeter());
                    performance = performance.add(subRule.getPerformance());
                    detail.append("调度距离绩效: ")
                            .append(NumberUtil.toStr(subRule.getPerformance()))
                            .append("(")
                            .append(subRule.getDistanceMeter())
                            .append("米);");
                    DispatchPerformanceLog performanceLog = new DispatchPerformanceLog();
                    BeanUtil.copyProperties(dp, performanceLog, "performance", "performanceDetail", "remark");
                    performanceLog.setPerformance(subRule.getPerformance());
                    performanceLog.setPerformanceDetail("调度距离绩效: " + NumberUtil.toStr(subRule.getPerformance()) + "(" + subRule.getDistanceMeter() + "米);");
                    performanceLog.setRuleType(PerformanceRuleType.DISTANCE.getValue());
                    performanceLog.setRemark("MAIN-DISTANCE-调度距离");
                    performanceLogs.add(performanceLog);
                    break;
                }
            }
        }

        // 车辆标签
        // FIXME 标签删除后规则里的标签id不会自动删除
        if (config.getTagSolved() != null && config.getTagSolved().getEnabled()) {
            log.info("[调度绩效] 调度记录id: {}, 适用车辆标签绩效", dp.getDispatchLogId());
            List<TagBaseInfo> tags = getTags(dl.getMachineId()); // 从缓存获取车辆标签

            for (TagSolvedRule subRule : config.getTagSolved().getSubRules()) {
                for (TagBaseInfo tag : tags) {
                    if (subRule.getTagIds().contains(Long.parseLong(tag.getId()))) {
                        performance = performance.add(subRule.getPerformance());
                        detail.append("车辆标签绩效: ")
                                .append(NumberUtil.toStr(subRule.getPerformance()))
                                .append("(标签: ")
                                .append(tag.getName())
                                .append(");");
                        DispatchPerformanceLog performanceLog = new DispatchPerformanceLog();
                        BeanUtil.copyProperties(dp, performanceLog, "performance", "performanceDetail", "remark");
                        performanceLog.setPerformance(subRule.getPerformance());
                        performanceLog.setPerformanceDetail("车辆标签绩效: " + NumberUtil.toStr(subRule.getPerformance()) + "(标签:" + tag.getName() + ");");
                        performanceLog.setRuleType(PerformanceRuleType.MACHINE_TAG.getValue());
                        performanceLog.setRemark("MAIN-MACHINE_TAG-车辆标签：" + tag.getName());
                        performanceLogs.add(performanceLog);
                        break;
                    }
                }
            }

            redisService.del(DISPATCH_CURR_TAG_KEY + dl.getMachineId());
        }

        dp.setPerformance(performance);
        dp.setPerformanceDetail(detail.toString());
    }

    /**
     * 解析闲置时长优先级
     */
    public static String parseIdlePriority(int idlePriority) {
        switch (idlePriority) {
            case 0:
                return "短时";
            case 1:
                return "中时";
            case 2:
                return "长时";
            default:
                return "未知";
        }
    }

    /**
     * 更新绩效
     *
     * @param performanceId 绩效ID
     * @param performance   绩效值
     * @param remark        备注
     */
    @Transactional("logTransactionManager")
    public void updatePerformance(Long performanceId, BigDecimal performance, String remark) {
        DispatchPerformance update = getById(performanceId);
        BigDecimal oldPerformance = update.getPerformance();
        update.setPerformanceId(performanceId);
        update.setPerformance(performance);
        update.setRemark(remark);
        update.setPerformanceDetail("人工修改绩效: 总绩效" + NumberUtil.toStr(performance, true));
        update.setPerformanceType(PerformanceTypeConstant.MANUAL);
        updateById(update);
        // 计算新旧绩效差值，用于新增一条绩效日志记录dispatch_performance_log
        BigDecimal subPerformance = performance.subtract(oldPerformance);
        if (subPerformance.compareTo(BigDecimal.ZERO) == 0) {
            return;
        }
        // 记录绩效日志  业务类型设置为人工， 绩效为新旧绩效的差值
        DispatchPerformanceLog log = new DispatchPerformanceLog();
        BeanUtil.copyProperties(update, log, "remark");
        log.setPerformance(subPerformance);
        log.setRuleType(PerformanceRuleType.MANUAL.getValue());
        log.setRemark("MAIN-人工修改绩效: " + NumberUtil.toStr(oldPerformance, true) + " -> " + NumberUtil.toStr(performance, true));
        performanceLogService.save(log);
    }

    /**
     * 插入零绩效记录
     *
     * @param dispatchLogDb 调度记录
     */
    public void insertZeroPerformance(DispatchLog dispatchLogDb) {
        DispatchPerformance dispatchPerformance = new DispatchPerformance();
        dispatchPerformance.setDispatchLogId(dispatchLogDb.getDispatchLogId());
        dispatchPerformance.setPerformance(BigDecimal.ZERO);
        dispatchPerformance.setPerformanceDetail("");
        dispatchPerformance.setAccountId(dispatchLogDb.getAccountId());
        Date dispatchTime = DateUtil.parse(dispatchLogDb.getDispatchTime());
        int hour = DateUtil.hour(dispatchTime, true);
        if (hour >= 0 && hour < 6) {
            dispatchPerformance.setDispatchInterval(1);
        } else if (hour >= 6 && hour < 12) {
            dispatchPerformance.setDispatchInterval(2);
        } else if (hour >= 12 && hour < 18) {
            dispatchPerformance.setDispatchInterval(3);
        } else if (hour >= 18 && hour < 24) {
            dispatchPerformance.setDispatchInterval(4);
        }
        if (dispatchLogDb.getFirstOrderTime() != null) {
            dispatchPerformance.setFirstOrderDuration(
                    (int) DateUtil.between(DateUtil.parse(dispatchLogDb.getFirstOrderTime()),
                            DateUtil.parse(dispatchLogDb.getFinishTime()),
                            DateUnit.MINUTE)
            );
        }
        dispatchPerformance.setOrderCountAfter24Hour(0);
        dispatchPerformance.setRemark("无效改有效系统自动生成;");
        save(dispatchPerformance);
    }

    /**
     * 删除调度绩效记录
     *
     * @param dispatchLogId 调度记录ID
     */
    @Transactional("logTransactionManager")
    public void removePerformance(Integer dispatchLogId) {
        DispatchPerformance dispatchPerformance = getOne(Wrappers.<DispatchPerformance>query()
                .eq(DispatchPerformance.Fields.dispatchLogId, dispatchLogId));
        if (dispatchPerformance == null) {
            return;
        }
        if (BigDecimal.ZERO.compareTo(dispatchPerformance.getPerformance()) != 0){
            // 增加一条绩效日志详情记录 dispatch_performance_log
            DispatchPerformanceLog log = new DispatchPerformanceLog();
            BeanUtil.copyProperties(dispatchPerformance, log, "remark");
            log.setPerformance(dispatchPerformance.getPerformance().negate());// 取绩效负数
            log.setRuleType(PerformanceRuleType.MANUAL.getValue());
            log.setRemark("MAIN-MANUAL-手动修改调度日志从有效改为无效-自动添加");
            performanceLogService.save(log);
        }
        removeById(dispatchPerformance.getPerformanceId());
    }

    @Transactional("logTransactionManager")
    public void generatePerformance(DispatchLog dispatchLog, BigDecimal performanceValue) {
        if (performanceValue != null && performanceValue.compareTo(BigDecimal.ZERO) < 0) {
            throw new BaseException("绩效值不能小于0");
        }
        // 获取绩效记录
        DispatchPerformance dp = getOne(Wrappers.<DispatchPerformance>query()
                .eq(DispatchPerformance.Fields.dispatchLogId, dispatchLog.getDispatchLogId())
        );
        if (dp == null) {
            log.info("[调度绩效] 生成新绩效记录, 调度记录id: {},performanceValue:{}", dispatchLog.getDispatchLogId(), performanceValue);
            dp = createDispatchPerformance(dispatchLog);
            if (performanceValue != null){
                dp.setPerformance(performanceValue);
                dp.setPerformanceDetail("main-修改有效性同时修改绩效");
                // 设置人工修改的标志，被人工修改之后，后面的绩效计算不再考虑这条记录。
                dp.setPerformanceType(PerformanceTypeConstant.MANUAL);
                save(dp);
                // 记录绩效日志  业务类型设置为人工， 绩效为新旧绩效的差值
                DispatchPerformanceLog log = new DispatchPerformanceLog();
                BeanUtil.copyProperties(dp, log, "remark");
                log.setPerformance(performanceValue);
                log.setPerformanceDetail("main-人工修改绩效值");
                log.setRuleType(PerformanceRuleType.MANUAL.getValue());
                log.setRemark("main-修改有效性同时修改绩效: " + NumberUtil.toStr(performanceValue, true));
                performanceLogService.save(log);
            }else {
                List<DispatchPerformanceLog> performanceLogs = new ArrayList<>();
                // 通过规则计算绩效值
                calculatePerformance(dispatchLog, dp, performanceLogs);
                save(dp);
                // 保存绩效日志
                if (!performanceLogs.isEmpty()) {
                    // 填充绩效记录id
                    Long performanceId = dp.getPerformanceId();
                    performanceLogs.forEach(performanceLog -> performanceLog.setPerformanceId(performanceId));
                    performanceLogService.insertBatch(performanceLogs);
                }
            }
        }else {
            // 已经存在绩效记录
            if (performanceValue != null) {
                log.info("[调度绩效] 已经存在绩效记录,修改绩效, 调度记录id: {},绩效记录id: {},performanceValue:{}", dispatchLog.getDispatchLogId(), dp.getPerformanceId(), performanceValue);
                BigDecimal oldPerformance = dp.getPerformance();
                // 需要修改绩效值
                dp.setPerformance(performanceValue);
                dp.setPerformanceDetail("main-修改有效性同时修改绩效");
                // 设置人工修改的标志，被人工修改之后，后面的绩效计算不再考虑这条记录。
                dp.setPerformanceType(PerformanceTypeConstant.MANUAL);
                // 计算新旧绩效差值，用于新增一条绩效日志记录dispatch_performance_log
                BigDecimal subPerformance = performanceValue.subtract(oldPerformance);
                if (subPerformance.compareTo(BigDecimal.ZERO) != 0) {
                    // 记录绩效日志  业务类型设置为人工， 绩效为新旧绩效的差值
                    DispatchPerformanceLog log = new DispatchPerformanceLog();
                    BeanUtil.copyProperties(dp, log, "remark");
                    log.setPerformance(subPerformance);
                    log.setRuleType(PerformanceRuleType.MANUAL.getValue());
                    log.setRemark("main-修改有效性同时修改绩效: " + NumberUtil.toStr(oldPerformance, true) + " -> " + NumberUtil.toStr(performanceValue, true));
                    performanceLogService.save(log);
                }
                updateById(dp);
            }
        }
    }

    private DispatchPerformance createDispatchPerformance(DispatchLog dispatchLog) {
        DispatchPerformance dp = new DispatchPerformance();
        dp.setDispatchLogId(dispatchLog.getDispatchLogId());
        dp.setAccountId(dispatchLog.getAccountId());
        Date dispatchTime = DateUtil.parse(dispatchLog.getDispatchTime());
        dp.setOrderCountAfter24Hour(0);
        List<TagBaseInfo> tags = getTags(dispatchLog.getMachineId());
        if (!tags.isEmpty()) {
            dp.setBeforeTag(tags.stream()
                    .map(TagBaseInfo::getName)
                    .collect(Collectors.joining(",")));
        }
        // 挪车前状态
        List<Integer> abnormalCache = getAbnormalCache(dispatchLog.getMachineId());
        if (!abnormalCache.isEmpty()) {
            StringBuilder abnormalTypes = new StringBuilder();
            for (Integer abnormalType : abnormalCache) {
                abnormalTypes.append(MachineAbnormalConstant.parse(abnormalType))
                        .append(",");
            }
            dp.setBeforeStatus(abnormalTypes.substring(0, abnormalTypes.length() - 1));
        }
        // 调度时段
        int hour = DateUtil.hour(dispatchTime, true);
        if (hour >= 0 && hour < 6) {
            dp.setDispatchInterval(1);
        } else if (hour >= 6 && hour < 12) {
            dp.setDispatchInterval(2);
        } else if (hour >= 12 && hour < 18) {
            dp.setDispatchInterval(3);
        } else if (hour >= 18 && hour < 24) {
            dp.setDispatchInterval(4);
        }
        return dp;
    }

    /**
     * @description: 根据设置的当前用户的运维权限获取绩效数据
     * @author: mo.shanyong
     * @date: 2025/5/12 11:13
     * @param: req
     * @param: loginAccountUser
     * @return: java.util.List<com.tbit.main.pojo.maintain_performance.stat.PerformanceOverviewResp>
     */
    private List<PerformanceOverviewResp> getPerformanceList(PerformanceOverviewReq req,AccountUser loginAccountUser){
        //数据权限（0全部，1仅自己）
        req.setAccountUserId(Objects.equals(loginAccountUser.getRole().getDataPermission(),1) ? loginAccountUser.getAccountUserId() : null);
        return getBaseMapper().queryOverviewPage(req);
    }
}
